package com.yusvn.scm.admin.service;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.jfinal.aop.Inject;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.yusvn.scm.common.BaseService;
import com.yusvn.scm.common.constant.Const;
import com.yusvn.scm.common.kit.RetKit;
import com.yusvn.scm.common.kit.UserAgentGetter;
import com.yusvn.scm.common.model.SysLoginRecord;
import com.yusvn.scm.common.model.SysSession;
import com.yusvn.scm.common.model.SysUser;

import cn.hutool.core.date.DateUtil;

/**
 * 登录业务
 * @author liugz
 *
 */
public class LoginService extends BaseService {
	
	@Inject
	AdminRoleService roleSrv;
	
	@Inject
	AdminMenuService menuSrv;
	
	private SysUser userDao = new SysUser().dao();
	private SysSession sessionDao = new SysSession().dao();
	
	//登录
	public RetKit doLogin(String username,String password, HttpServletRequest request){
		if (StrKit.isBlank(username) || StrKit.isBlank(password)) {
			return RetKit.fail("用戶名或密码不能为空");
		}
		username = username.toLowerCase().trim();
		password = password.trim();
		
		SysUser user = userDao.findFirst("select * from sys_user where username = ? limit 1", username);
		//System.out.println(" user:"+user);
		
		if (user == null) {
			createLoginLog(username, SysLoginRecord.TYPE_ERROR, "账号不存在", request);//生成登陆日志
			return RetKit.fail("账号不存在");
		}
		if(user.isStateLock()){
			createLoginLog(username, SysLoginRecord.TYPE_ERROR, "账号被禁用", request);//生成登陆日志
			return RetKit.fail("账号被禁用");
		}
		
		String salt = user.getSalt();
		String hashPassword = HashKit.sha256(salt + password);
		if (hashPassword.equals(user.getPassword())) {
			//判断当前有用户是否登录
			int dlyhCnt = Db.queryInt("select count(*) from sys_session "
					+ "where user_id=(select user_id from sys_user where username=?)", username);
			if(dlyhCnt>0) {
				return RetKit.fail("当前用户已经登录，请先注销登录");
			}
			
			// 过期时间天数，跟前端保持一致(单位秒)
			long liveSeconds =  Const.TOKEN_EXPIRE_TIME;
			// expireAt 用于设置 session 的过期时间点，需要转换成毫秒
			//long expireAt = System.currentTimeMillis() + (liveSeconds * 1000); //当前时间+过期时间
			long expireAt = DateUtil.endOfDay(DateUtil.date() ).getTime() + (liveSeconds * 1000); //当前时间的最晚时间+过期时间
			// 生成sessionId
			String sessionId =  HashKit.sha256(StrKit.getRandomUUID());
			// 保存登录 session 到数据库
			SysSession session = new SysSession();
			session.setId(sessionId);
			session.setUserId(user.getUserId());
			session.setExpireat(expireAt);
			session.setCreateTime(new Date());
			session.save();
			
			createLoginLog(username, SysLoginRecord.TYPE_LOGIN, null, request);//生成登陆日志
			
			return RetKit.ok().put("access_token", sessionId);
		} else {
			createLoginLog(username, SysLoginRecord.TYPE_ERROR, "密码错误", request);//生成登陆日志
			return RetKit.fail("密码错误");
		}
	}

	//注销登录
	public RetKit quitout(String username,String password, HttpServletRequest request){
		if (StrKit.isBlank(username) || StrKit.isBlank(password)) {
			return RetKit.fail("用戶名或密码不能为空");
		}
		username = username.toLowerCase().trim();
		password = password.trim();
		
		SysUser user = userDao.findFirst("select * from sys_user where username = ? limit 1", username);
		//System.out.println(" user:"+user);
		
		if (user == null) {
			createLoginLog(username, SysLoginRecord.TYPE_ERROR, "账号不存在", request);//生成登陆日志
			return RetKit.fail("账号不存在");
		}
		if(user.isStateLock()){
			createLoginLog(username, SysLoginRecord.TYPE_ERROR, "账号被禁用", request);//生成登陆日志
			return RetKit.fail("账号被禁用");
		}
		
		String salt = user.getSalt();
		String hashPassword = HashKit.sha256(salt + password);
		if (hashPassword.equals(user.getPassword())) {
			Db.delete("delete from sys_session where user_id=(select user_id from sys_user where username=?)", username);
			
			return RetKit.ok("用户注销成功");
		} else {
			return RetKit.fail("密码错误");
		}
	}
	
	
	/**
	 * 退出登录
	 * @param sessionId
	 */
	public void logout(String sessionId, HttpServletRequest request) {
		if (StrKit.notBlank(sessionId)) {
			SysUser sysUser = getUserBySessionId(sessionId);

			//生成登陆日志
			createLoginLog(sysUser.getUsername(), SysLoginRecord.TYPE_LOGOUT, null, request);
			
			//CacheKit.remove(CacheConstant.SYS_USER, sessionId); //清除缓存
			sessionDao.deleteById(sessionId);
		}
	}
	
	/**
	 * 根据用户id获取用户信息
	 * @param userid
	 * @return
	 */
	public String getErpUserId(Object userid, String cid) {
		SysUser sysUser = userDao.findById(userid);
		String erpUsercode = sysUser.getPhone(); //原ERP用户编号
		String erpUserid = "1"; //默认系统管理员
		if(StrKit.notBlank(erpUsercode)) {
			erpUserid = Db.use(Const.SCMDB).queryStr("SELECT id FROM SYSUSER WHERE cid=? and usercode=? ", cid, erpUsercode);
			//System.out.println(" erpUserid:"+erpUserid);
		}
		return erpUserid;
	}
	
	/**
	 * 根据用户id获取用户信息
	 * @param userid
	 * @return
	 */
	public SysUser getUserById(Object userid) {
		return userDao.findById(userid);
	}

	/**
	 * 根据sessionId获取用户信息
	 * @param sessionId
	 * @return
	 */
	public SysUser getUserBySessionId(String sessionId) {
		SysSession session = sessionDao.findById(sessionId);
		return userDao.findById(session.getUserId());
	}
	
	/**
	 * 根据sessionId检验登录用户信息是否合法
	 * @param sessionId
	 * @param request
	 * @return
	 */
	//后期考虑存缓存， TODO
	public SysUser loginWithSessionId(String sessionId, HttpServletRequest request) {
		SysSession session = sessionDao.findById(sessionId);
		if (session == null) {      
			return null;
		}
		// 被动式删除过期数据，此外还需要定时线程来主动清除过期数据
		if (session.isExpired()) {
			session.delete();		
			return null;
		}
		
		SysUser loginSysUser = userDao.findById(session.getUserId());
		// 找到 loginSysUser 并且 是正常状态 才允许登录
		if (loginSysUser != null && loginSysUser.isStateOk()) {
			loginSysUser.removeSensitiveInfo(); //移除密码等敏感信息
			// 往user放一份sessionId
			loginSysUser.put("sessionId", sessionId);
			
			return loginSysUser;
		}
		return null;
	}

	/**
	 * 创建登录日志
	 */
	public void createLoginLog(String username, Integer type, String comments, HttpServletRequest request) {
		if (username == null) return;
		
		SysLoginRecord loginRecordDao = new SysLoginRecord();
		loginRecordDao.setUsername(username);
		loginRecordDao.setOperType(type);
		loginRecordDao.setComments(comments);
        UserAgentGetter agentGetter = new UserAgentGetter(request);
        loginRecordDao.setOs(agentGetter.getOS());
        loginRecordDao.setDevice(agentGetter.getDevice());
        loginRecordDao.setBrowser(agentGetter.getBrowser());
        loginRecordDao.setIp(agentGetter.getIp());
		
		loginRecordDao.save();
	}
	
	/**
	 * 系统配置信息
	 * @return List<Record> 
	 */
	public List<Record> getSysConfig() {
		return Db.find("SELECT dict_data_id as id, dict_data_code as configcode, dict_data_name as configname, comments as configvalue "
				+ "FROM sys_dictionary_data where dict_id=(select dict_id from sys_dictionary where dict_code='sys_config')");
	}
}
